iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Modern Web

現在就學React.js 系列 第 13

列表渲染與key值 - Day13

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240927/20159895o7CxeCXKgf.png

今天要來學習的是列表渲染,在 React 中列表渲染,
會使用到JavaScript 的陣列方法的 map函式。
map 允許我們遍歷陣列後,並返回一個新的 JSX 元素陣列。

常用在要動態顯示在 UI 上,例如顯示一列待辦事項、商品列表或卡片等,都會用到列表渲染的功能。
能用來渲染多種資料類型與結構,有 HTML 標籤、子元件,甚至是 JavaScript 表達式或其他類型的資料。

我們來看一個簡單的範例:

function App() {
  const numbers = [1, 2, 3, 4, 5];
  return (
    <ul>
      {numbers.map((number) => (
        <li>{number}</li>
      ))} 
    </ul>
  );
}

export default App;

渲染出來後,HTML 的標籤就是等於

 <ul>
     <li>1</li>
     <li>2</li>
     <li>3</li>
     <li>4</li>
     <li>5</li>
 </ul>

列表渲染 初步上是完成了,接下來回頭把Day07的卡片範例,
做個列表渲染的調整吧!範例如下:

import './App.css';
import Card from './component/Card';

function App() {
  return (
    <>
      <Card title="Card title 1" content="This is the content 1" />
      <Card title="Card title 2" content="This is the content 2" />
      <Card title="Card title 3" content="This is the content 3" />
      <Card title="Card title 4" content="This is the content 4" />
    </>
  )
}

export default App;

剛剛上一個的渲染的範例是 li 標籤,接下來我們做 子元件 的渲染,改成列表渲染後。

  • 提取出資料陣列:使用 cardData 陣列來存放每個卡片的資料,包含 titlecontent
  • map() 函式:利用 map() 函式遍歷 cardData 陣列,動態生成 Card 元件,並將資料作為 props 傳遞給每個 Card
import './App.css';
import Card from './component/Card';

function App() {
  const cardData = [
    { title: 'Card title 1', content: 'This is the content 1' },
    { title: 'Card title 2', content: 'This is the content 2' },
    { title: 'Card title 3', content: 'This is the content 3' },
    { title: 'Card title 4', content: 'This is the content 4' },
  ];

  return (
    <>
      {cardData.map((card) => (
        <Card title={card.title} content={card.content} />
      ))}
    </>
  );
}

export default App;

https://ithelp.ithome.com.tw/upload/images/20240927/20159895y8FxjEqoCd.png

就在我們都以為完成的時候,這時打開開發者工具看一下,會發現竟然有個警告訊息!

Warning: Each child in a list should have a unique "key" prop.

KEY值是什麼?

在 React 中,key 是用於幫助 React 識別列表中的每一個元素。當列表中的元素改變(例如新增、刪除或重新排序),React 需要透過 key 來判斷哪些元素發生了變化,進而高效地更新 DOM。

React 背後有一個虛擬 DOM(Virtual DOM),當列表中的資料改變時,React 會先比較舊的虛擬 DOM 與新的虛擬 DOM,並只更新改變的部分。而 key 會幫助 React 快速確定哪些元素發生了變化,進而提升渲染效率。

我們就把剛剛的範例,加上 key,看是否就不會跳出警告訊息了。

//略

  return (
    <>
      {cardData.map((card,index) => (
        <Card key={index} title={card.title} content={card.content} />
      ))}
    </>
  );
}

export default App;

目前看起來是沒問題了但其實還潛在一個可能會出現的問題。
就是使用 index 索引值來當作 key

為何 key={index} 不是最佳做法

key 設定為 index,在大部分情況下是可以的,但並不是最佳做法。

當列表中的元素順序發生變化時,使用索引作為 key 會導致 React 無法正確追蹤每個元素。
這可能會出現預期外的狀況,例如錯誤的元件更新等。

那該用什麼當作 key呢?
元素間的唯一值,這樣 React 才能正確地識別每個元素。

因此,我們可以這樣調整:

import './App.css';
import Card from './component/Card';

function App() {
  const cardData = [
    { id:1, title: 'Card title 1', content: 'This is the content 1' },
    { id:2, title: 'Card title 2', content: 'This is the content 2' },
    { id:3, title: 'Card title 3', content: 'This is the content 3' },
    { id:4, title: 'Card title 4', content: 'This is the content 4' },
  ];

  return (
    <>
      {cardData.map((card) => (
        <Card key={card.id} title={card.title} content={card.content} />
      ))}
    </>
  );
}

export default App;

結論

  • 在 React 中,使用 map()函式可以輕鬆地進行列表渲染。
  • key 值的選擇是要唯一且穩定的, React 才能正確地識別每個元素。
  • 儘量避免使用索引作為 key ,有助於提升渲染效率。

參考資料:

後記

本文將會同步更新到我的部落格

黃禎平 – Medium


上一篇
再探 Props 與 State - Day12
下一篇
條件渲染的幾種方式-Day14
系列文
現在就學React.js 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言